例-2020-0527修饰符 sync自定义组件
对element-ui的el-dialog进行封装,应该怎样处理visible?
使用vue2.4新加的特性 $attrs $listeners
<el-dialog :visible.sync="mVisible">
props: {
visible: {
type: Boolean,
default: false
},
},
computed: {
mVisible: {
get() {
return this.visible
},
set(s) {
this.$emit('update:visible', s);
}
}
}
实战1:
子组件使用了v-model:
<van-list v-model="mShowLoading" :finished="showFinished" @load="onLoad">
//此时应该在computed重新监听返回新的值:
computed: {
mShowLoading: {
get() {
return this.showLoading
},
set(newVal) {
this.$emit('update:showLoading', newVal)
}
},
父组件
<Single @findListParent="findProductsList" :totalBuyNum="totalShopNumber.totalBuyNum" :products="products" :show-loading.sync="showLoading" :show-finished.sync="loadingFinished" />
实战2:
外层有用sync修饰符
vue 修饰符sync的功能是:当一个子组件改变了一个 prop 的值时,这个变化也会同步到父组件中所绑定。如果我们不用.sync,我们想做上面的那个弹窗功能,我们也可以props传初始值,然后事件监听,实现起来也不算复杂。这里用sync实现,只是给大家提供一个思路,让其明白他的实现原理,可能有其它复杂的功能适用sync。
在有些情况下,我们可能需要对一个 prop 进行“双向绑定”。不幸的是,真正的双向绑定会带来维护上的问题,因为子组件可以修改父组件,且在父组件和子组件都没有明显的改动来源。
这也是为什么我们推荐以 update:my-prop-name 的模式触发事件取而代之。举个例子,在一个包含 title prop 的假设的组件中,我们可以用以下方法表达对其赋新值的意图:
this.$emit('update:title', newTitle)
父:
<BottomPopCom :show-shop-pic-select.sync="showShopPicSelect" v-if="showShopPicSelect" />
methods: {
bgAddAction() {
this.showShopPicSelect = true
}
}
组件:
<template>
<van-popup :style="{ height: 'auto' }" position="bottom" v-model="isShow">
<van-cell :border="false" :clickable="true" @click="shopPicSelect(0)">
<template slot="title">
<div class="customShowPicCell">
<span>拍照</span>
</div>
</template>
</van-cell>
<van-cell :border="false" :clickable="true" @click="shopPicSelect(1)">
<template slot="title">
<div class="customShowPicCell">
<span>从相册选择</span>
</div>
</template>
</van-cell>
<div class="blank"></div>
<van-cell :clickable="true" @click="shopPicSelect(2)">
<template slot="title">
<div class="customShowPicCell">
<span>取消</span>
</div>
</template>
</van-cell>
</van-popup>
</template>
<script>
export default {
name: 'BottomPopCom',
props: {
showShopPicSelect: {
type: Boolean,
default: false
// default: true
},
title: {
type: String,
default: '选择活动商品'
},
actType: {
type: Number,
default: 1
}
},
data() {
return {
isShow: true
}
},
computed: {},
watch: {
isShow(newVal) {
if (!newVal) {
this.$emit('update:showShopPicSelect', false)
}
}
},
mounted() {},
methods: {
shopPicSelect(flag) {
switch (flag) {
case 0:
console.log('拍照')
this.isShow = false
break
case 1:
console.log('相册')
this.isShow = false
break
case 2:
console.log('取消')
this.isShow = false
break
default:
break
}
}
}
}
</script>
<style lang="scss" scoped>
</style>